{

Parallax Flick-It Prize Picker
Version 1.2
February 8th, 2011


Program written by: Daniel Harris

This program is free of copyright.  Feel free to take this code and use it however you want.
                              
}
con
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  VibraTabPin   = 7
  

var

  byte num_contestants
  byte flicked

  byte already[256]
  
  long flick_stack[20]


obj

  pst:  "Parallax Serial Terminal"
  rr:   "RealRandom"

dat

long
long
              '        10        20        30
              '12345678901234567890123456789012
name1   byte  "Louis Yassa                    ",0
name2   byte  "William Betz                   ",0
name3   byte  "Alex Dickman                   ",0
name4   byte  "Steve Nicholson                ",0
name5   byte  "Andrew Williams                ",0                                                                   
name6   byte  "Laine Walker-Avina             ",0
name7   byte  "Bob Olson                      ",0
name8   byte  "Gregg Erickson                 ",0
name9   byte  "Scout Handford                 ",0
name10  byte  "Cody Watson                    ",0
name11  byte  "Mark Headrick                  ",0
name12  byte  "Ben Conger                     ",0
name13  byte  "Matt Stemple                   ",0
name14  byte  "Nida Murray                    ",0
name15  byte  "Rick Murray                    ",0
name16  byte  "Tim Ballas                     ",0
name17  byte  "William Hardie                 ",0
name18  byte  "Justin Weber                   ",0
name19  byte  "Janet Dunlop                   ",0
name20  byte  "Charles Phillips               ",0
name21  byte  "Jermoe Munroe                  ",0
name22  byte  "Ivonne                         ",0
name23  byte  "                               ",0
name24  byte  "                               ",0
name25  byte  "                               ",0
name26  byte  "                               ",0
name27  byte  "                               ",0
name28  byte  "                               ",0
name29  byte  "                               ",0
name30  byte  "                               ",0
name31  byte  "                               ",0
name32  byte  "                               ",0
name33  byte  "                               ",0
name34  byte  "                               ",0
name35  byte  "                               ",0
name36  byte  "                               ",0
name37  byte  "                               ",0
name38  byte  "                               ",0
name39  byte  "                               ",0
name40  byte  "                               ",0
name41  byte  "                               ",0



pub go | i, temp

  cognew(flick_me, @flick_stack)

  pst.start(115_200)
  

  rr.start

  waitcnt(cnt+clkfreq<<1)       'wait 2 seconds to let you enable the serial terminal
  
  repeat i from 0 to 255        'zero out the alrady picked array (because no one has been picked yet)
    already[i]~

  num_contestants~
  
  'count the number of names entered.  looks for things that dont start with a " " (space).
  repeat until byte[@name1 + num_contestants*32] ==  " "
    num_contestants++

  'main loop
  repeat
    pst.clear
    pst.str(STRING("=====  Parallax Flick-It Prize Picker  =====", 13, 13))
     
    pst.str(STRING("Today, we have "))
    pst.dec(num_contestants)
    pst.str(STRING(" contestants participating.", 13, 13))
     
    pst.str(STRING("           Whose it gonna be??!!?!?", 13))
         
    flicked~     'make sure the flicked variable is clear

    'print randomized names at a set rate until the vibra tab sensor has been flicked.
    repeat until flicked 
      pst.Position(0, 7)
      repeat                       
        i := (rr.random & $7FFF_FFFF)//num_contestants
      while already[i] > 0      'make sure we havent already picked this person
      print_name(i)
      pause(50_000)

    
    'sensor has been flicked.  Print some names (10 of them) and slow down until the winner is picked
    repeat i from 0 to 10
      pst.Position(0, 7)
      repeat                       
        temp := (rr.random & $7FFF_FFFF)//num_contestants
      while already[temp] > 0      'make sure we havent already picked this person
      print_name(temp)
      pause(50_000 * i<<1)    
                                                                   
    'winner is picked here.  If the personal has already been chosen, pick another
    repeat
      i := (rr.random & $7FFF_FFFF)//num_contestants    'picks the winner
    while already[i] > 0                                'does the check
    
    already[i] := 1             'mark the winner as having been picked

    pst.Position(0, 7)
    print_name(i)               'print the winner's name

    'blink the gratz line a few times
    repeat 5
      pst.position(0,6)
      pst.str(STRING("           "))
      pst.str(STRING("Congratulations!!!!!!"))
      pause(400_000)
      pst.position(0,6)
      pst.str(STRING("                                                      "))
      pause(400_000)



pub print_name(name_idx) | j, old

' Given the index of the name to print, this method determines the length of the name and automatically prints it centered

  j := 0
  repeat until byte[@name1 + (name_idx * 32) + j] == " " and old == " "
    old := byte[@name1 + (name_idx * 32) + j]
    j++

  j := (45 - j)>>1

  repeat j
    pst.str(STRING(" "))

  pst.str(@name1 + (name_idx*32))


pub flick_me

  dira[VibraTabPin]~            'make it an input

  flicked~
  repeat
    repeat until flicked
      flicked := ina[VibraTabPin]     'did we flick it?  If so, wait 1 second, clear the results, and do it again.
    waitcnt(cnt + clkfreq)
    flicked~ 
  
    
pri Pause(duration)

  'This function pauses program execution for approximately [duration] micro seconds
  'so 1_000_000 would be approximately one second.  Doesnt account for instruction
  'execution time overhead.

  if duration < 381
    duration := 381             'lower bound limit. anything lower than this, we
                                'have to wait until the counter comes back around,
                                'which is MUCH longer than [duration].
  waitcnt(((clkfreq / 1_000_000) * duration) + cnt)    
  